using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using TrueCode.DependencyManager.BuildActions.Injection;
using TrueCode.DependencyManager.Interface;

namespace TrueCode.DependencyManager.Services.Parameters
{
  public class TypedParameterProvider : IParameterProvider
  {
    private readonly Dictionary< Type, object > _values = new Dictionary< Type, object >();

    public TypedParameterProvider( params object[] parameters )
      : this( parameters.Select( p => p as TypedValue ?? new TypedValue( p ) ) )
    {
    }

    public TypedParameterProvider( params TypedValue[] parameters ) : this( ( IEnumerable< TypedValue > )parameters )
    {
    }

    public TypedParameterProvider( IEnumerable< TypedValue > parameters )
    {
      foreach( var parameter in parameters )
        _values.Add( parameter.Type, parameter.Value );
    }

    #region Implementation of IParameterValueProvider
    public object[] GetValuesFor( IBuildSession context, ParameterInfo[] parameterInfo )
    {
      var values = new object[parameterInfo.Length];

      var defaultService = context.GetDefaultService< IParameterProvider >();

      for( var i = 0; i < values.Length; i++ )
      {
        if( !_values.TryGetValue( parameterInfo[ i ].ParameterType, out values[ i ] ) )
          values[ i ] = context.MakeCopy( parameterInfo[ i ].ParameterType ).Build();
      }
      return values;
    }
    #endregion
  }
}